﻿using System.Collections.Generic;
using Ah.Testudin.Engine.Actors.Components;
using Ah.Testudin.Engine.Actors.Components.Animation;
using Ah.Testudin.Engine.Actors.Components.Collision;
using Ah.Testudin.Engine.Actors.Components.Render;
using Ah.Testudin.Engine.Content;
using Ah.Testudin.Engine.Events;
using Ah.Testudin.Engine.Graphics.Scenes;
using Ah.Testudin.Engine.Physics;
using Ah.Testudin.Engine.UI.Elements;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Ah.Testudin.Engine.Actors.Spawning
{
    public class MissileActorBuilder : IActorBuilder
    {
        #region Private Member Variables

        private const float GRAVITY_ACCELERATION = 1.32f;

        private readonly ITestudinContentManager _contentManager;

        private readonly IEventManager _eventManager;

        private readonly IPhysicsSimulator _physicsSimulator;

        #endregion

        #region Constructors

        public MissileActorBuilder(
            ITestudinContentManager contentManager,
            IEventManager eventManager,
            IPhysicsSimulator physicsSimulator)
        {
            _contentManager = contentManager;

            _eventManager = eventManager;

            _physicsSimulator = physicsSimulator;
        }

        #endregion

        #region IActorBuilder

        public Actor BuildActor(Matrix transform)
        {
            Actor missileActor = new Actor(
                ActorIdGenerator.GetNextActorId());

            Model missileModel = _contentManager.Load<Model>("Content/Models/missile");

            missileActor.SetComponent<TransformComponent>(
                new TransformComponent(
                    missileActor,
                    transform));

            missileActor.SetComponent<PhysicsComponent>(
                new PhysicsComponent(
                    missileActor,
                    Shape.Capsule,
                    transform,
                    new Vector3(
                        .5f,
                        .75f,
                        .5f),
                    GRAVITY_ACCELERATION,
                    _physicsSimulator,
                    _eventManager));

            missileActor.SetComponent<ModelRenderComponent>(
                new ModelRenderComponent(
                    missileActor,
                    missileModel,
                    RenderPass.DynamicActor,
                    _eventManager));

            Matrix rotation = 
                transform *
                Matrix.CreateFromAxisAngle(
                    Vector3.Cross(
                        Vector3.Normalize(transform.Forward),
                        Vector3.Normalize(transform.Down)),
                    MathHelper.PiOver2);

            IAnimationComponent rotationAnimation = new RotationAnimationComponent(
                missileActor,
                rotation.Forward,
                _eventManager,
                30000f);

            missileActor.SetComponent<IAnimationComponent>(rotationAnimation);

            missileActor.SetComponent<ICollisionHandlerComponent>(
                new CollisionHandlerComponentComposite(
                    missileActor,
                    _eventManager,
                    new List<ICollisionHandlerComponent>()
                    {
                        new StopAnimationCollisionHandlerComponent(
                            missileActor,
                            _eventManager),

                        new ExplosionCollisionHandlerComponent(
                            missileActor,
                            _eventManager,
                            5f,
                            .2f,
                            10)
                    }));

            return missileActor;
        }

        #endregion
    }
}
